package cn.innosmart.aq.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.List;

/**
 * Created by David on 2015/9/14.
 */
public class LocationUtil {
    public LocationClient mLocationClient = null;
    public BDLocationListener myListener = new MyLocationListener();
    public Context context;
    public double latitude;
    public double lontitude;
    private LocationCallBack locationCallBack;

    private LocationUtil() {

    }

    public static LocationUtil getInstance() {
        return LocationUtilInstance.instance;
    }


    public void initLocationUtil(Context context) {
        this.context = context;
        clearLocation(context);
        mLocationClient = new LocationClient(context);     //声明LocationClient类
        mLocationClient.registerLocationListener(myListener);
        initLocation();
    }

    /**
     * 开始定位
     *
     * @param locationCallBack 回掉函数
     */
    public void startLocation(LocationCallBack locationCallBack) {
        setLocationCallBack(locationCallBack);
        mLocationClient.start();
    }

    public void startLocation() {
        mLocationClient.start();
    }

    public void stopLocation() {
        mLocationClient.stop();
    }

    /**
     * 初始化定位工具
     */
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span = 0;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(true);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认false，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
        mLocationClient.setLocOption(option);
    }

    /**
     * 记录位置信息
     *
     * @param context
     * @param latitude
     * @param longitude
     * @param city
     */
    private void writeLocation(Context context, double latitude, double longitude, String city) {
        SharedPreferences sp = context.getSharedPreferences("Location", context.MODE_PRIVATE);
        this.lontitude = longitude;
        this.latitude = latitude;
        sp.edit().putString("latitude", String.valueOf(latitude)).commit();
        sp.edit().putString("longitude", String.valueOf(longitude)).commit();
        sp.edit().putString("city", city).commit();
    }

    /**
     * 清除位置信息
     *
     * @param context
     */
    private void clearLocation(Context context) {
        SharedPreferences sp = context.getSharedPreferences("Location", context.MODE_PRIVATE);
        sp.edit().clear().commit();
    }

    /**
     * 读取位置信息
     *
     * @param context
     * @return
     */
    public JSONObject readLocation(Context context) {
        SharedPreferences sp = context.getSharedPreferences("Location", context.MODE_PRIVATE);
        String la = sp.getString("latitude", null);
        String lo = sp.getString("longitude", null);
        String ci = sp.getString("city", null);
        System.out.println("la=" + la + "lo=" + lo);
        double latitude, longitude;
        String city;
        if (TextUtils.isEmpty(la)) {
            latitude = 0;
        } else {
            latitude = Double.valueOf(la);
        }
        if (TextUtils.isEmpty(lo)) {
            longitude = 0;
        } else {
            longitude = Double.valueOf(lo);
        }
        if (TextUtils.isEmpty(ci)) {
            city = null;
        } else {
            city = ci;
        }
        JSONObject jsonObject = new JSONObject();
        System.out.println("latitude=" + latitude + "longitude=" + longitude);
        try {
            jsonObject.put("latitude", latitude);
            jsonObject.put("longitude", longitude);
            jsonObject.put("city", city);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public void setLocationCallBack(LocationCallBack locationCallBack) {
        this.locationCallBack = locationCallBack;
    }

    public interface LocationCallBack {
        void onSuccessResultCallBack(String address);

        void onFailedCallBack();
    }

    private static class LocationUtilInstance {
        private static final LocationUtil instance = new LocationUtil();
    }

    /**
     * 定位回调信息
     */
    class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            //Receive Location
            StringBuffer sb = new StringBuffer(256);
            sb.append("time : ");
            sb.append(location.getTime());
            sb.append("\nerror code : ");
            sb.append(location.getLocType());
            sb.append("\nlatitude : ");
            sb.append(location.getLatitude());
            sb.append("\nlontitude : ");
            sb.append(location.getLongitude());
            sb.append("\nCity : ");
            sb.append(location.getCity());
            sb.append("\nCityCode : ");
            sb.append(location.getCityCode());
            sb.append("\nradius : ");
            sb.append(location.getRadius());
            if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                sb.append("\nspeed : ");
                sb.append(location.getSpeed());// 单位：公里每小时
                sb.append("\nsatellite : ");
                sb.append(location.getSatelliteNumber());
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 单位：米
                sb.append("\ndirection : ");
                sb.append(location.getDirection());// 单位度
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                sb.append("\ndescribe : ");
                sb.append("gps定位成功");
                writeLocation(context, location.getLatitude(), location.getLongitude(), location.getCity());
                if (locationCallBack != null)
                    locationCallBack.onSuccessResultCallBack(location.getLocationDescribe());
                mLocationClient.stop();
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                //运营商信息
                sb.append("\noperationers : ");
                sb.append(location.getOperators());
                sb.append("\ndescribe : ");
                sb.append("网络定位成功");
                writeLocation(context, location.getLatitude(), location.getLongitude(), location.getCity());
                if (locationCallBack != null)
                    locationCallBack.onSuccessResultCallBack(location.getLocationDescribe());
                mLocationClient.stop();
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                sb.append("\ndescribe : ");
                sb.append("离线定位成功，离线定位结果也是有效的");
                writeLocation(context, location.getLatitude(), location.getLongitude(), location.getCity());
                if (locationCallBack != null)
                    locationCallBack.onSuccessResultCallBack(location.getLocationDescribe());
                mLocationClient.stop();
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("\ndescribe : ");
                sb.append("服务端网络定位失败，可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com，会有人追查原因");
                if (locationCallBack != null)
                    locationCallBack.onFailedCallBack();
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("\ndescribe : ");
                sb.append("网络不同导致定位失败，请检查网络是否通畅");
                if (locationCallBack != null)
                    locationCallBack.onFailedCallBack();
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("\ndescribe : ");
                sb.append("无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机");
                if (locationCallBack != null)
                    locationCallBack.onFailedCallBack();
            }
            sb.append("\nlocationdescribe : ");
            sb.append(location.getLocationDescribe());// 位置语义化信息
            List<Poi> list = location.getPoiList();// POI数据
            if (list != null) {
                sb.append("\npoilist size = : ");
                sb.append(list.size());
                for (Poi p : list) {
                    sb.append("\npoi= : ");
                    sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
                }
            }
            Log.i("BaiduLocationApiDem", sb.toString());
        }
    }


}
